E) Class Memory structure

1. Empty Class
#include <cstdio>
class Empty{};
int main(void){
Empty inst;
printf("sizeof(inst)==%lu\n", sizeof(inst));
return 0;
}

sizeof(inst)==1

Empty* pa=new Empty();
Empty* pb=new Empty();
위와 같은 경우, 만일 빈 클래스가 0 바이트 메모리를 할당한다면, heap의 사용 증가가 없기 때문에,
pa와 pb에 같은 메모리가 저장되게 된다. 이를 방지하기 위해 빈 클래스도 1바이틀 차지한다.
2. 필드를 가진 클래스
class FieldSample{
char ch1;
}; // 1
class FieldSample{
char ch1;
char ch2;
}; // 2
class FieldSample{
char ch1;
int n1;
char ch2;
}; // ch1, ch2 4 12
#pragma pack(1) // 1
class FieldSample{
public:
char ch1;
int n1;
char ch2;
}; // ch1, ch2 1 6
3. 멤버함수를 가진 단일 클래스
함수는 메모리에 변화를 주지않는다.(함수는 코드 영역에 별도로 저장되고, static 변수는 전역 변수 공간에 저장)
virtual function의 경우, virtual function table(vtable)이 생성되어 포인터를 하나 필요로 함
#include <cstdio>
class FieldFuncSample{
public:
int n1=1;
void func1(){}
};
class FieldFuncSample_v{
public:
int n1=1;
void func1(){}
virtual void vfunc1(){}
};
int main(void){
FieldFuncSample inst;
FieldFuncSample_v inst_v;
printf("sizeof(inst)==%lu\n", sizeof(inst));
printf("sizeof(inst_v)==%lu\n", sizeof(inst_v));
return 0;
}

sizeof(inst)==4

sizeof(inst_v)==16

내부적으로 64비트 컴퓨터는 포인터에 8바이트를 사용하며, 필드로 인해 int(4바이트) 또한 8바이트 공간 차지
4. 단일 상속 클래스
#include <cstdio>
class A{
public:
int n1=1;
void func1(){ n1++; }
virtual void vfunc1() {}
};
class BonA: A{
public:
int n2=2;
void func2(){ n2++; }
virtual void vfunc2() {}
};
class ConBonA: BonA{
public:
int n3=2;
void func3(){ n3++; }
};
int main(void){
BonA inst;
ConBonA inst2;
printf("sizeof(inst)==%lu\n", sizeof(inst));
printf("sizeof(inst2)==%lu\n", sizeof(inst2));
return 0;
}

sizeof(inst)==16

sizeof(inst2)==24

클래스를 상속 받을 때,
메모리는 vtable을 가장 아래에 할당하고, 이후에 Base Class 멤버부터, Derived Class 멤버순으로 할당한다.
(vtable은 상속받은 개체에는 기록되지 않는다.)
5. 단일 상속 클래스의 형 변환
위와 같은 순서로 데이터가 저장되기 때문에, 단순히 부모클래스 포인터에 자식 클래스의 주소값을 대입해도
해당 범위(부모클래스)까지만 읽는다.
ConBonA* pInst=new ConBonA();
BonA* pbInst=(BonA*)pInst;
A* paInst=(A*)pInst;
00B71B8E  mov         eax, [new로 할당받은 힙 주소]
00B71B9B  mov         dword ptr [ebp-34h],eax  // pInst 변수에 ConBonA* 타입의 this 포인터 보관

        BonA *pbInst = (BonA *)pInst;
00B71BB1  mov         dword ptr [ebp-40h],eax  // pbInst 변수에 BonA* 타입의 this 포인터 보관

        A *paInst = (A *)pInst;
00B71BB7  mov         dword ptr [ebp-4Ch],eax  // paInst 변수에 A* 타입의 this 포인터 보관
https://www.sysnet.pe.kr/2/0/11164